/**
 * 表单验证，依赖jquery
 * 
 * demo: <div> <input verify="type:must" /> </div> demo说明：验证的元素必须有一个
 * 父级元素包裹，验证的元素 添加 verify属性，值为 Verify对象中的types元素
 * 
 * @author 尘无尘
 * @data 2017-6-30 22:33:22
 */

var double_reg = /^\d+(\.\d{1,3})?$/;
var positive_int_reg=/^\d+$/;

var Verify = {
	"my":{
//		"closePrompt":function(e){},//关闭提示信息，可以自己实现
//		"openPrompt":function(e){},//开启提示信息，可以自己实现
	},
	"types" : {
		"positiveInt" : {
			"verify" : function(elem) {
				value = elem.value.trim();
				if (value && !positive_int_reg.test(value)) {
					return "只能是数字";
				} else {
					return Verify.conf.okRes;
				}

				return positive_int_reg.test(value);
			}
		},
		"float" : {
			"verify" : function(elem) {
				value = elem.value.trim();
				if (value && !double_reg.test(value)) {
					return "只能是整数或者最多三位小数";
				} else {
					return Verify.conf.okRes;
				}
				return double_reg.test(value);
			}
		},
		"must" : {
			"verify" : function(elem) {
				if (elem.value == "") {
					return "此处为必填项";
				} else {
					return Verify.conf.okRes;
				}
			}
		},
		"number" : {
			"verify" : function(elem) {
				value = elem.value.trim();
				if (value && isNaN(value)) {
					return "此处只能填写数字";
				} else {
					return Verify.conf.okRes;
				}
			}
		}
	},
	"doVerify" : function(e, isPrompt) {// 执行 验证 ，e:要验证的 元素 或者 包含 要验证的元素的元素（jquery对象或者js对象 ）， isPrompt：是否 提示验证 信息
		var elems=Verify.privat.getEleAry(e);
		var errorAry = [];
		for (var i = 0; i < elems.length; i++) {
			var res=Verify.privat.doVerify(elems[i]);
			if (res != true) {
                errorAry.push({
                    "elem": elems[i],
                    "msg": res
                });
                if (isPrompt == true) {
                    Verify.openPrompt(elems[i], res);
                }
			}
		}
		return errorAry;
	},
	"openPrompt" : function(e, msg) {//提示，es:要验证的 元素(js对象 ）,msg：提示 信息
			e.msgStatus="show";
			Verify.privat.addSty(e);
			if(Verify.my.openPrompt){
				Verify.my.openPrompt(e, msg);
				return;
			}
			var jq=$(e);
			var box = jq.parent().find(".lrvf-prom-point");
			if (box.length == 0) {
				jq.parent().addClass("lrvf-prom-box-parent").append(
						Verify.conf.promptHtml);
				box = jq.parent().find(".lrvf-prom-point");
				var info = box.find(".info").html(msg);
	//			box.width(140);
			} else if (msg) {
				box.find(".info").html(msg);
			}
			box.show().width(msg.length*15);
	},
	"closePrompt" : function(es) {//关闭提示 ，e:要验证的 元素 或者 包含 要验证的元素的元素（jquery对象或者 js对象 ）
		var elems=Verify.privat.getEleAry(es);
		for(var i=0;i<elems.length;i++){
			if(elems[i].msgStatus=="close"){
				continue;
			}
			elems[i].msgStatus="close";
			Verify.privat.remSty(elems[i]);
			 
			if(Verify.my.closePrompt){
				Verify.my.closePrompt(elems[i]);
				continue;
			}
			$(elems[i]).parent().find(".lrvf-prom-point").hide();
		}
		
	},
	"conf":{
		"okRes":true,  //验证正确的结果
		"errorClass":"lrvf-error",//给验证错误的元素添加该类名称
		"verifyEventsName":["keyup","focus"],//执行验证的事件
		"closePromptEventsName":["blur"],//关闭提示信息的事件
		"promptHtml" : "<div class=\"lrvf-prom-point\">"//提示信息html
			+ "<div class=\"lrvf-prom-box\" ></div>"
			+ "<span class=\"info\"></span>" + "</div>",
	},
	"start" : function() {
		this.add();
	},

	"remove" : function(elems) {//移除验证元素 ，elems:要验证的 元素 或者 包含 要验证的元素的元素（jquery对象或者 js对象 ）
		var es=Verify.privat.getEleAry(elems);
		for (var i = 0; i < es.length; i++) {
			es[i].disableVerify=true;
		}
	},
	"add" : function(elems) {//新增验证元素 ，elems:要验证的 元素 或者 包含 要验证的元素的元素（jquery对象或者 js对象 ）
		if(elems){
			elems=Verify.privat.getEleAry(elems);
		}else{
			//获取 所有 需要 验证的 元素 
			elems=$("input[verify],select[verify],textarea[verify]");
		}
		var verifys = [];
		var jq,verifysAry;
		for (var i = 0; i < elems.length; i++) {
			jq=$(elems[i]);
//			if(Verify.switchVerify(elems[i]) == true){
			if(elems[i].disableVerify == true){
				elems[i].disableVerify=false;
				continue;
			}
			
			verifysAry = Verify.privat.parseConf(jq.attr('verify'));
			elems[i].verifys=verifysAry;
			if (verifysAry.length > 0) {
				var vs=Verify.conf.verifyEventsName;
				for(var n=0;n<vs.length;n++){
					jq[vs[n]](function() {
						Verify.privat.doVerify(this);
					});
				}
				vs=Verify.conf.closePromptEventsName;
				for(var n=0;n<vs.length;n++){
					jq.blur(function() {
						Verify.closePrompt(this);
					});
				}

		 }
		}
	},
	"privat":{
		"addSty":function(e){
			$(e).addClass(Verify.conf.errorClass);
		},
		"remSty":function(e){
			$(e).removeClass(Verify.conf.errorClass);
		},
		"doVerify":function(ele){
			var res=Verify.conf.okRes;
			if (ele.disableVerify == true) {
				Verify.closePrompt(ele);
				return true;
			}
			for (var i = 0; i < ele.verifys.length; i++) {
				 res = ele.verifys[i]["verify"](ele);
				if (res !== Verify.conf.okRes) {
					Verify.openPrompt(ele, res);
					break;
				} else if (i == ele.verifys.length - 1) {
					Verify.closePrompt(ele);
				}
			}
			return res;
		},
		"getEleAry":function(e){//e:要验证的（或者包含要验证的）js或者jquery对象，返回要验证的js数组
			var elems=[];
			if(!e.verifys){
				var mye=null;
				if(e instanceof jQuery){
					if(e[0].verifys){
						elems.push(e[0]);
						return elems;
					}else{
						mye=e;
					}
				}else{
					mye = $(e);
				}
				elems = mye.find("input[verify],select[verify],textarea[verify]");
			}else{
				elems.push(e);
			}
			return elems;
		},
		"parseConf":function(conf){
			var verifys=[];
			if(!conf){
				return verifys;
			}
			var lastChar=conf.substr(conf.length-1);
			var lastFlag=false;
			if(lastChar!=="]"&&lastChar!=="}"){
				conf+=",";
				lastFlag=true;
			}
			var reBeforConf=conf;
			for(var k in Verify.types){
				conf=reBeforConf.replace(k+",","");
				if(conf.length<reBeforConf.length){
					verifys.push(Verify.types[k]);
				}
				reBeforConf=conf;
				if(!conf){
					break;
				}
			}
			
			if(conf){
				if(lastFlag){
					conf=conf.substr(0,conf.length-1);
				}
				conf = conf.myReplace(":", "\":\"").myReplace(",", "\",\"").myReplace("}", "\"}").myReplace("]", "\"]")
				.myReplace("}\"", "}").myReplace("]\"", "]")
				.myReplace("\"{", "{\"").myReplace("\"\\[", "[\"");
				conf='{"types":{"'+conf+'}}';
				conf=JSON.parse(conf);
				for(var k in conf.types){
					try{
						conf.types[k]["verify"]=Verify.types[k]["verify"];
						verifys.push(conf.types[k]);
					}catch(e){
						continue;
					}
				}
			}
			return verifys;
		}
	}
};
String.prototype.myReplace=function(f,e){//吧f替换成e
    var reg=new RegExp(f,"g"); //创建正则RegExp对象   
    return this.replace(reg,e); 
}
